package jffile;

/**
 * Created : Apr 28, 2012
 *
 * @author pquiring
 */

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javaforce.*;
import javaforce.jbus.*;

public class MapNetworkShareDialog extends javax.swing.JDialog {

  /**
   * Creates new form MapNetworkShare
   */
  public MapNetworkShareDialog(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();
    setPosition();
    listDrives();
    Mappings.loadMaps();
    jbusClient = new JBusClient("org.jflinux.jfile." + Math.abs(new Random().nextInt())
      , new JBusMethods());
    jbusClient.start();
    JFAWT.assignHotKey(this, accept, KeyEvent.VK_ENTER);
    JFAWT.assignHotKey(this, cancel, KeyEvent.VK_ESCAPE);
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    server = new javax.swing.JTextField();
    jLabel2 = new javax.swing.JLabel();
    share = new javax.swing.JTextField();
    jPanel1 = new javax.swing.JPanel();
    mapWineDrive = new javax.swing.JCheckBox();
    wineDrive = new javax.swing.JComboBox();
    accept = new javax.swing.JButton();
    cancel = new javax.swing.JButton();
    jLabel3 = new javax.swing.JLabel();
    username = new javax.swing.JTextField();
    jLabel4 = new javax.swing.JLabel();
    password = new javax.swing.JPasswordField();
    guest = new javax.swing.JCheckBox();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    setTitle("Map Network Share");
    setResizable(false);

    jLabel1.setText("Server");

    jLabel2.setText("Share");

    jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Wine Integration"));

    mapWineDrive.setText("Map to Wine Drive");
    mapWineDrive.setEnabled(false);

    wineDrive.setEnabled(false);

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
          .addComponent(mapWineDrive, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addComponent(wineDrive, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addContainerGap(251, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addComponent(mapWineDrive)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addComponent(wineDrive, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    accept.setText("Accept");
    accept.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        acceptActionPerformed(evt);
      }
    });

    cancel.setText("Cancel");
    cancel.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        cancelActionPerformed(evt);
      }
    });

    jLabel3.setText("Username");

    username.setEnabled(false);

    jLabel4.setText("Password");

    password.setEnabled(false);

    guest.setSelected(true);
    guest.setText("Connect as Guest");
    guest.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        guestActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
            .addComponent(guest)
            .addGap(0, 0, Short.MAX_VALUE))
          .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jLabel1)
              .addComponent(jLabel2))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(share)
              .addComponent(server)))
          .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addGap(0, 0, Short.MAX_VALUE)
            .addComponent(cancel)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(accept))
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jLabel3)
              .addComponent(jLabel4))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(password)
              .addComponent(username))))
        .addContainerGap())
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel1)
          .addComponent(server, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel2)
          .addComponent(share, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(guest)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel3)
          .addComponent(username, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel4)
          .addComponent(password, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(accept)
          .addComponent(cancel))
        .addContainerGap())
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelActionPerformed
    dispose();
  }//GEN-LAST:event_cancelActionPerformed

  private void acceptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_acceptActionPerformed
    if (!valid()) return;
    setState(false);
    String _server = server.getText();
    String _share = share.getText();
    target = getTarget();
    String user = "guest";
    pass = "";
    if (!guest.isSelected()) {
      user = username.getText();
      pass = new String(password.getPassword());
    }
    uri = "smb://" + user + "@" + _server + "/" + _share;
    link = "null";
    if (mapWineDrive.isSelected()) {
      String drive = (String)wineDrive.getSelectedItem();
      link = getDrive(drive);
    }
    dialog = this;
    jbusClient.call("org.jflinux.jdesktop." + System.getenv("JID"), "mount",
      quote(jbusClient.pack) + "," + quote(uri) + "," + quote(target) + ","
      + quote(pass) + "," + quote(link));
  }//GEN-LAST:event_acceptActionPerformed

  private void guestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_guestActionPerformed
    if (guest.isSelected()) {
      username.setEnabled(false);
      password.setEnabled(false);
    } else {
      username.setEnabled(true);
      password.setEnabled(true);
    }
  }//GEN-LAST:event_guestActionPerformed

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton accept;
  private javax.swing.JButton cancel;
  private javax.swing.JCheckBox guest;
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JLabel jLabel4;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JCheckBox mapWineDrive;
  private javax.swing.JPasswordField password;
  private javax.swing.JTextField server;
  private javax.swing.JTextField share;
  private javax.swing.JTextField username;
  private javax.swing.JComboBox wineDrive;
  // End of variables declaration//GEN-END:variables

  private JBusClient jbusClient;
  private boolean hasWine = false;

  private void listDrives() {
    File file = new File(JF.getUserPath() + "/.wine/dosdevices");
    if (!file.exists()) return;
    File drives[] = file.listFiles();
    boolean avail[] = new boolean[26];
    for(int a=0;a<26;a++) avail[a] = true;
    for(int a=0;a<drives.length;a++) {
//      System.out.println(drives[a].getName());
//      System.out.println(drives[a].getAbsolutePath());
//      try{System.out.println(drives[a].getCanonicalFile()); } catch (Exception e) {System.out.println(""+e);}
      char ch = drives[a].getName().toLowerCase().charAt(0);
      if ((ch < 'a') || (ch > 'z')) continue;
      avail[ch - 'a'] = false;
    }
    wineDrive.removeAllItems();
    for(int a=3;a<26;a++) {   //don't show A,B,C
      if (avail[a]) {
        wineDrive.addItem("" + (char)('a' + a) + ':');
      }
    }
    if (wineDrive.getItemCount() == 0) return;
    mapWineDrive.setEnabled(true);
    wineDrive.setEnabled(true);
    hasWine = true;
  }

  private boolean valid() {
    boolean ok = true;
    if (server.getText().length() == 0) {
      server.setBackground(Color.red);
      ok = false;
    } else {
      server.setBackground(Color.white);
    }
    if (share.getText().length() == 0) {
      share.setBackground(Color.red);
      ok = false;
    } else {
      share.setBackground(Color.white);
    }
    username.setBackground(Color.white);
    password.setBackground(Color.white);
    if (guest.isSelected()) return ok;
    if (username.getText().length() == 0) {
      username.setBackground(Color.red);
      ok = false;
    }
    if (password.getPassword().length == 0) {
      password.setBackground(Color.red);
      ok = false;
    }
    return ok;
  }

  private static String getTarget() {
    Random r = new Random();
    String folder;
    do {
      folder = JF.getUserPath() + "/.gvfs/" + Math.abs(r.nextInt()) + "/";
    } while (new File(folder).exists());
    return folder;
  }

  private static String getDrive(String drive) {
    return JF.getUserPath() + "/.wine/dosdevices/" + drive;
  }

  private void setPosition() {
    Rectangle s = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
    Dimension d = getSize();
    setLocation(s.width/2 - d.width/2, s.height/2 - (d.height/2));
  }

  private static String target, uri, link, pass;

  public static void main(String args[]) {
    //usage : jmapshare server share [x:]
    if (args.length < 2) {
      System.out.println("Usage: jmapshare server share [x:] [--user=user] [--pass=pass]");
      System.out.println(" Note: DOMAINNAME and PASSWORD environment variables are used by default");
      System.exit(1);
    }
    Mappings.loadMaps();
    String _server = args[0], _share = args[1];
    target = getTarget();
    String user = System.getenv("DOMAINNAME");
    pass = System.getenv("PASSWORD");
    String drive = null;
    for(int a=2;a<args.length;a++) {
      if (args[a].startsWith("--user=")) user = args[a].substring(7);
      if (args[a].startsWith("--pass=")) pass = args[a].substring(7);
      if (args[a].length() == 2) drive = args[a];
    }
    user += "\n";
    pass += "\n";
    uri = "smb://" + user + "@" + _server + "/" + _share;
    if (drive != null) {
      link = getDrive(drive);
    } else {
      link = "null";
    }
    isMain = true;
    JBusClient jbusClient = new JBusClient("org.jflinux.jfile." + Math.abs(new Random().nextInt())
      , new JBusMethods());
    jbusClient.start();
    JFLog.log("mount:calling:" + "org.jflinux.jdesktop." + System.getenv("JID"));
    jbusClient.call("org.jflinux.jdesktop." + System.getenv("JID"), "mount",
      quote(jbusClient.pack) + "," + quote(uri) + "," + quote(target) + ","
      + quote(pass) + "," + quote(link));
  }

  private void setState(boolean state) {
    accept.setEnabled(state);
    server.setEnabled(state);
    share.setEnabled(state);
    guest.setEnabled(state);
    if (guest.isSelected()) {
      username.setEnabled(state);
      password.setEnabled(state);
    }
    if (hasWine) {
      mapWineDrive.setEnabled(state);
      wineDrive.setEnabled(state);
    }
  }

  private static boolean isMain = false;
  private static MapNetworkShareDialog dialog;

  public static class JBusMethods {
    public void mountSuccess(String uri) {
      Mappings.addMap(uri, target, pass, link);
      Mappings.saveMaps();
      if (isMain) {
        System.out.println("Success");
        System.exit(0);
      } else {
        dialog.dispose();
      }
    }
    public void mountFail(String uri) {
      if (isMain) {
        System.out.println("Failed");
        System.exit(0);
      } else {
        JFAWT.showError("Error", "Failed to connect to share");
        dialog.setState(true);
      }
    }
  }

  private static String quote(String str) {
    return "\"" + str + "\"";
  }
}
